/**
 * 
 */
package es.amh.management;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import com.google.gdata.client.GoogleService.InvalidCredentialsException;
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.util.AuthenticationException;

import es.amh.data.BirthdayEntry;

/**
 * Proporciona todos los mecanismos necesarios para obtener una lista de
 * cumpleaños de una agenda concreta dada.
 * 
 * @author ahiges
 * 
 */
public class BirthdayManagement {

	private final Logger log = Logger.getLogger(this.getClass()
			.getCanonicalName());

	private boolean connected = false;

	private static BirthdayManagement management;

	private ContactsService service;

	// TODO sacar del fichero de config
	private final String calendarURL = "https://www.google.com/m8/feeds/contacts/default/full?max-results=100";

	/**
	 * Init the service, but doesn't connect
	 */
	private BirthdayManagement() {
		service = new ContactsService("M&MSoft-birthdayupdater-1.0");
	}

	/**
	 * Devuelve la instancia de BirthdayManagement
	 * 
	 * @return
	 */
	public static BirthdayManagement getInstance() {
		if (management == null) {
			management = new BirthdayManagement();
			return management;
		}
		return management;
	}

	/**
	 * Conecta el servicio con los datos dados
	 * 
	 * @param _user
	 * @param _password
	 * @return ok, si la conexión ha sido exitosa false en caso contrario
	 */
	public boolean connectService(String _user, String _password) {

		try {
			service.setUserCredentials(_user, _password);
			connected = true;
			return true;
		} catch (InvalidCredentialsException e) {
			return false;
		} catch (AuthenticationException e) {
			return false;
		}
	}

	/**
	 * Devuelve una lista de todos los cumpleaños almacenados en la agenda a la
	 * que está conectada el servicio
	 * 
	 * @return Lista de cumpleaños en formato birthdayEntry (listo para subir)
	 * @throws Exception
	 *             Si no estamos conectados
	 */
	public List<BirthdayEntry> getListOfContact() throws Exception {
		if (connected) {
			long initTime = System.currentTimeMillis();
			URL feedUrl = new URL(this.calendarURL);

			List<BirthdayEntry> birthdayList = new ArrayList<BirthdayEntry>();
			ContactFeed resultFeed = (ContactFeed) service.getFeed(feedUrl,
					ContactFeed.class);
			boolean continua = true;
			while (continua) {
				for (ContactEntry entry : resultFeed.getEntries()) {
					if (entry.hasBirthday()) {
						BirthdayEntry birthEntry = new BirthdayEntry(entry
								.getName().getFullName().getValue(), entry
								.getBirthday().getWhen(), true, true, true);
						birthdayList.add(birthEntry);
					}

				}
				if (resultFeed.getNextLink() != null) {
					URL nextFeed = new URL(resultFeed.getNextLink().getHref());
					resultFeed = (ContactFeed) service.getFeed(nextFeed,
							ContactFeed.class);
				} else {
					continua = false;
				}
			}
			long endTime = System.currentTimeMillis();
			log.info(birthdayList.size() + " birthday recovered in "
					+ (endTime - initTime) + " millis");
			return birthdayList;
		} else {
			log.warning("Service not connected");
			throw new Exception("Service not connected");
		}

	}
}
